package com.ybkj.daijia.api.apirest.v4;

import com.alibaba.fastjson.JSONObject;
import com.ybkj.daijia.serverUtils.HttpClientUtil;
import com.ybkj.daijia.OrderConfirmLocs;
import com.ybkj.daijia.ServiceSetting;
import com.ybkj.daijia.serverUtils.ServiceUtil;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.WxSetting;
import com.ybkj.daijia.api.beatpay.utils.BestPayCreateOrder;
import com.ybkj.daijia.api.beatpay.utils.BestPayOrderModel;
import com.ybkj.daijia.api.beatpay.utils.CryptTool;
import com.ybkj.daijia.api.driver.Error;
import com.ybkj.daijia.api.driver.ErrorConstant;
import com.ybkj.daijia.api.driver.transport.ResultTransport;
import com.ybkj.daijia.api.member.alipay.config.AlipayConfig;
import com.ybkj.daijia.api.member.alipay.sign.MemberOrderSign;
import com.ybkj.daijia.api.member.alipay.sign.RSA;
import com.ybkj.daijia.api.member.alipay.util.AlipayNotify;
import com.ybkj.daijia.api.unionpay.AcpService;
import com.ybkj.daijia.api.unionpay.DemoBase;
import com.ybkj.daijia.api.unionpay.LogUtil;
import com.ybkj.daijia.api.unionpay.SDKConfig;
import com.ybkj.daijia.api.unionpay.SDKConstants;
import com.ybkj.daijia.api.util.ErrorConstantV4;
import com.ybkj.daijia.api.weixin.tenpayv3.Configuration;
import com.ybkj.daijia.api.weixin.tenpayv3.GetWxOrderno;
import com.ybkj.daijia.api.weixin.tenpayv3.RequestHandler;
import com.ybkj.daijia.api.weixin.tenpayv3.Sha1Util;
import com.ybkj.daijia.api.weixin.tenpayv3.TenpayUtil;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.config.SalesApi;
import com.ybkj.daijia.config.ZhuanxianApi;
import com.ybkj.daijia.server.errand.SelectPrice;
import com.ybkj.daijia.server.event.model.OrderEmployHasPayEvent;
import com.ybkj.daijia.server.event.model.OrderPassengerHasPayEvent;
import com.ybkj.daijia.server.event.model.zhuanxian.ZhuanxianOrderConfirmEvent;
import com.ybkj.daijia.server.mapper.CompanyMapper;
import com.ybkj.daijia.server.mc.Enterprise;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Area;
import com.ybkj.daijia.server.model.ChargeStartDistance;
import com.ybkj.daijia.server.model.ChargeStartTime;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.FirstOrderPassenger;
import com.ybkj.daijia.server.model.OrderLocation;
import com.ybkj.daijia.server.model.OrderLocationMany;
import com.ybkj.daijia.server.model.SmsTemplet;
import com.ybkj.daijia.server.sales.Coupon;
import com.ybkj.daijia.server.sales.CouponRule;
import com.ybkj.daijia.server.sales.CouponRule.CouponType;
import com.ybkj.daijia.server.service.AreaService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.CouponService;
import com.ybkj.daijia.server.service.DriverHelppayService;
import com.ybkj.daijia.server.service.DriverRefuseRecordService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.ErrandService;
import com.ybkj.daijia.server.service.FirstOrderPassengerService;
import com.ybkj.daijia.server.service.FreightService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.OrderLocationManyService;
import com.ybkj.daijia.server.service.OrderService;
import com.ybkj.daijia.server.service.SmsService;
import com.ybkj.daijia.server.service.WxBindService;
import com.ybkj.daijia.server.service.ZhuancheService;
import com.ybkj.daijia.server.service.ZhuanxianService;
import com.ybkj.daijia.server.zhuanxian.Line;
import com.ybkj.daijia.server.zhuanxian.Order;
import com.ybkj.daijia.server.zhuanxian.Order.PayTypeDetails;
import com.ybkj.daijia.server.zhuanxian.PayRecordOrder;
import com.ybkj.daijia.server.zhuanxian.PayRecordOrder.PayRecordTypeOrder;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@Controller("ApiZhuanchexianProcessController")
@RequestMapping(value = "api/zhuanxian")
public class ZhuanxianProcessController {
    @Autowired
    private ZhuanxianService zhuanxianService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ZhuancheService zhuancheService;
    @Autowired
    private ErrandService errandService;
    @Autowired
    private FreightService freightService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DriverService driverService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private WxBindService wxBindService;
    @Autowired
    private DriverRefuseRecordService driverRefuseRecordService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;
    @Autowired
    private SmsService smsService;
    @Autowired
    private SalesApi salesApi;
    @Autowired
    private OrderLocationManyService orderLocationManyService;
    @Autowired
    private FirstOrderPassengerService firstOrderPassengerService;
    @Autowired
    private DriverHelppayService helppayService;

    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private ZhuanxianApi zhuanxianApi;

    /**
     * 获取请求参数中所有的信息.
     *
     * @param request
     * @return
     */
    public static Map<String, String> getAllRequestParam(final HttpServletRequest request) {
        Map<String, String> res = new HashMap<String, String>();
        Enumeration<?> temp = request.getParameterNames();
        if (null != temp) {
            while (temp.hasMoreElements()) {
                String en = (String) temp.nextElement();
                String value = request.getParameter(en);
                res.put(en, value);
                // 在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
                if (null == res.get(en) || "".equals(res.get(en))) {
                    res.remove(en);
                }
            }
        }
        return res;
    }

    /**
     * 查询是否开起随机红包
     *
     * @return
     */
    @RequestMapping("isRandomRedPacket")
    @ResponseBody
    public Map<String, Object> isRandomRedPacket() {
        Map<String, Object> result = new HashMap<>();
        Setting setting = settingUtils.get();
        result.put("code", 0);
        result.put("message", "success");
        ServiceSetting serviceSetting = ServiceUtil.checkOpen();
        Map<String, Object> data = new HashMap<>();
//        Boolean isRandomRedPacket = serviceSetting.isRandomRedPacket();
//        String cycle = serviceSetting.getRedPacketCycle();
//        Double money = serviceSetting.getRedPacketMoney();
        Boolean isRandomRedPacket = setting.isRandomRedPacket();
        String cycle = setting.getRandomRedPacketCycle();
        Double money = setting.getRandomRedPacketMoney();
        data.put("isRandomRedPacket", isRandomRedPacket);
        data.put("cycle", cycle);
        data.put("money", money);
        result.put("data", data);
        return result;
    }

    /**
     * 接单成功发送短信，请求来自zhuanxian系统
     * 接单成功发送短信,并且重新设置driver的状态
     */
    @RequestMapping(value = "jiedanSms", method = RequestMethod.GET)
    @ResponseBody
    public void jiedanSms(@RequestParam("appKey") String appKey,
        @RequestParam("orderId") String orderId,
        @RequestParam("employName") String employName,
        @RequestParam("passengerId") String passengerId,
        @RequestParam("employPhone") String employPhone,
        @RequestParam("passengerPhone") String passengerPhone,
        @RequestParam("companyId") String companyId,
        @RequestParam("carNumber") String carNumber) {

        Company orderCompany = companyService.findOne(Long.parseLong(companyId));

        SmsTemplet templet = smsService
            .findByAlias(Long.parseLong(companyId), SmsTemplet.SmsType.acceptZhuanxianOrder);
        if (null != templet && StringUtils.isNotBlank(templet.getContent())) {
            try {
//                driverService.updateStatus(Driver.DRIVER_APPLY_ORDER, driver.getId());
                //int result = smsService.sendSms(passengerPhone, "acceptZhuanxianOrder", v, Long.parseLong(companyId), 0, orderCompany.getSignName());
                //短信发送（改）
                JSONObject smsParam = new JSONObject();
                smsParam.put("name", employName);
                smsParam.put("carNumber", carNumber);
                smsParam.put("tel", employPhone);
                int result = smsService
                    .sendSms(passengerPhone, templet.getTemplateId(), smsParam.toJSONString(),
                        Long.parseLong(companyId), 0, orderCompany.getSignName());
                System.out.println("短信发送结果：" + result);
            } catch (Exception e) {
                log.error("发送短信或更改司机状态发生异常：{}", e.getMessage());
            }
        }

    }

    /**
     * 根据线路的收费标准获取线路的收费
     *
     * @return
     */
    @RequestMapping(value = "getPrice", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> getPrice(@RequestParam("lineId") Long lineId) {
        Map<String, Object> result = new HashMap<String, Object>();
        BigDecimal money = BigDecimal.ZERO;
        try {
            if (lineId == null) {
                throw new RuntimeException("参数错误");
            }
            Line line = zhuanxianService.findByLine(lineId);

            Area area = areaService.findOneWithCharge(line != null ? line.getAreaId() : null);
            Area baocheArea = areaService
                .findOneWithCharge(line != null ? line.getBaocheAreaId() : null);
            Area jihuoArea = areaService
                .findOneWithCharge(line != null ? line.getJihuoAreaId() : null);
            Long time1 = 0L;
            Double mileage1 = 0.0;

            SelectPrice selectPrice = new SelectPrice();
            selectPrice.setPrice(time1, mileage1, area, null, 0D);

            SelectPrice baocheAreaPrice = new SelectPrice();
            baocheAreaPrice.setPrice(time1, mileage1, baocheArea, null, 0D);

            SelectPrice jihuoAreaPrice = new SelectPrice();
            jihuoAreaPrice.setPrice(time1, mileage1, jihuoArea, null, 0D);

            money = selectPrice.shouldCash;
            BigDecimal startPrice = selectPrice.qbCost;
            BigDecimal mileagePrice = selectPrice.disCost;
            BigDecimal travelTimePrice = selectPrice.travalTimeCost;
            ChargeStartTime price = selectPrice.getPrice();
            StringBuilder builder = new StringBuilder();
            builder.append("起步价:" + startPrice + "元\n");
            List<ChargeStartDistance> distances = price.getChargeStartDistances();

            if (distances != null && distances.size() != 0) {
                for (ChargeStartDistance d : distances) {
                    builder.append(
                        d.getStartdistance() + "公里到" + d.getDistance() + "公里内,加收" + d.getMoney()
                            + "元");
                    builder.append("\n");
                }
            }

            builder.append("超过" + price.getQblc() + "公里");
            builder.append("以后每" + price.getDjglUnit() + "公里");
            builder.append("加收" + price.getDjglCost() + "元");
            if (price.getDjglThresholdt() != 0) {
                builder.append("(不足" + price.getDjglThresholdt() + "公里不计费)");
            }
            builder.append("\n");
            builder.append("起步后" + price.getQbsj() + "分钟内不收费");
            builder.append("以后每" + price.getDjsjUnit() + "分钟");
            builder.append("加收" + price.getDjsjCost() + "元");
            if (price.getDjsjThresholdt() != 0) {
                builder.append("(不足" + price.getDjsjThresholdt() + "分钟不收费)");
            }
            builder.append("\n");
            builder.append("免费等候" + price.getMfdhsj() + "分钟");
            BigDecimal bigDecimal = price.getDhsjAtonceCost();

            if (bigDecimal.compareTo(BigDecimal.ZERO) == 1) {
                builder.append("到达则立即加收" + price.getDhsjAtonceCost() + "元");
            }
            builder.append("后每" + price.getDhsjUnit() + "分钟");
            builder.append("加收" + price.getDhsjCost() + "元");
            if (price.getDhsjThresholdt() != 0) {
                builder.append("(低于" + price.getDhsjThresholdt() + "分钟不计费)");
            }
            builder.append("\n");
            if (StringUtils.isNotBlank(area.getMemo())) {
                builder.append("备注:" + area.getMemo());
            }
            // result.put("success",true);
            // result.put("message","请求成功");
            if (money != null) {
                money = new BigDecimal(new DecimalFormat("0.0").format(money));
            } else {
                money = BigDecimal.ZERO;
            }
            // result.put("pincheMoney",money);
            // result.put("baocheMoney",(baocheAreaPrice.shouldCash!=null?new
            // BigDecimal(new
            // DecimalFormat("0.0").format(baocheAreaPrice.shouldCash)):BigDecimal.ZERO));
            // result.put("jihuoMoney",(jihuoAreaPrice.shouldCash!=null? new
            // BigDecimal(new
            // DecimalFormat("0.0").format(jihuoAreaPrice.shouldCash)):BigDecimal.ZERO));
            // result.put("travelTime",time1); //执行时间
            // result.put("startPrice",startPrice!=null?startPrice:0.0 ); //起步价
            // result.put("mileage",mileage1!=null?mileage1:0.0 ); //行驶里程
            // result.put("mileagePrice",mileagePrice!=null?mileagePrice:0.0 );
            // //行驶里程费用
            // result.put("travelTimePrice",travelTimePrice!=null?travelTimePrice:0.0
            // ); //服务时间费用

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("pincheMoney", money);
            map.put("baocheMoney", (baocheAreaPrice.shouldCash != null ? new BigDecimal(
                new DecimalFormat("0.0").format(baocheAreaPrice.shouldCash)) : BigDecimal.ZERO));
            map.put("jihuoMoney",
                (jihuoAreaPrice.shouldCash != null ? new BigDecimal(new DecimalFormat(
                    "0.0").format(jihuoAreaPrice.shouldCash)) : BigDecimal.ZERO));

            result.put("code", 0);
            result.put("message", "请求成功");
            result.put("data", map);
            return result;

        } catch (Exception e) {
            e.printStackTrace();
            result.put("code", 500);
            result.put("message", e.getMessage());
            result.put("data", null);
            return result;
        }

    }

    /**
     * 根据距离和时间按照公司的收费标准预估订单价格
     *
     * @param areaId
     * @param mileage1
     * @param time1
     * @return
     */
    @RequestMapping(value = "budgetedExpense ", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> getPrice(@RequestParam("areaId") Long areaId,
        @RequestParam("mileage") Double mileage1, @RequestParam("time") Long time1) {
        Map<String, Object> result = new HashMap<String, Object>();
        BigDecimal money = BigDecimal.ZERO;
        try {
            Area area = areaService.findOneWithCharge(areaId);

            SelectPrice selectPrice = new SelectPrice();
            selectPrice.setPrice(time1, mileage1, area, null, 0D);

            money = selectPrice.shouldCash;
            BigDecimal startPrice = selectPrice.qbCost;
            BigDecimal mileagePrice = selectPrice.disCost;
            BigDecimal travelTimePrice = selectPrice.travalTimeCost;
            ChargeStartTime price = selectPrice.getPrice();
            StringBuilder builder = new StringBuilder();
            builder.append("起步价:" + startPrice + "元\n");
            List<ChargeStartDistance> distances = price.getChargeStartDistances();

            if (distances != null && distances.size() != 0) {
                for (ChargeStartDistance d : distances) {
                    builder.append(
                        d.getStartdistance() + "公里到" + d.getDistance() + "公里内,加收" + d.getMoney()
                            + "元");
                    builder.append("\n");
                }
            }

            builder.append("超过" + price.getQblc() + "公里");
            builder.append("以后每" + price.getDjglUnit() + "公里");
            builder.append("加收" + price.getDjglCost() + "元");
            if (price.getDjglThresholdt() != 0) {
                builder.append("(不足" + price.getDjglThresholdt() + "公里不计费)");
            }
            builder.append("\n");
            builder.append("起步后" + price.getQbsj() + "分钟内不收费");
            builder.append("以后每" + price.getDjsjUnit() + "分钟");
            builder.append("加收" + price.getDjsjCost() + "元");
            if (price.getDjsjThresholdt() != 0) {
                builder.append("(不足" + price.getDjsjThresholdt() + "分钟不收费)");
            }
            builder.append("\n");
            builder.append("免费等候" + price.getMfdhsj() + "分钟");
            BigDecimal bigDecimal = price.getDhsjAtonceCost();

            if (bigDecimal.compareTo(BigDecimal.ZERO) == 1) {
                builder.append("到达则立即加收" + price.getDhsjAtonceCost() + "元");
            }
            builder.append("后每" + price.getDhsjUnit() + "分钟");
            builder.append("加收" + price.getDhsjCost() + "元");
            if (price.getDhsjThresholdt() != 0) {
                builder.append("(低于" + price.getDhsjThresholdt() + "分钟不计费)");
            }
            builder.append("\n");
            if (StringUtils.isNotBlank(area.getMemo())) {
                builder.append("备注:" + area.getMemo());
            }
            result.put("pay_detail", builder.toString());
            result.put("money", money != null ? money : 0.0);
            result.put("startPrice", startPrice != null ? startPrice : 0.0); // 起步价
            result.put("mileagePrice", mileagePrice != null ? mileagePrice : 0.0); // 行驶里程费用
            result
                .put("travelTimePrice", travelTimePrice != null ? travelTimePrice : 0.0); // 服务时间费用
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 0);
            map.put("data", result);
            map.put("message", "预算成功");
            return map;

        } catch (Exception e) {
            e.printStackTrace();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 500);
            map.put("data", null);
            map.put("message", e.getMessage());
            return result;
        }

    }

    /**
     * 根据距离和时间按照公司的收费标准预估订单价格
     *
     * @param areaId
     * @param startLat
     * @param startLng
     * @param endLat
     * @return
     */
    @RequestMapping(value = "wxBudgetedExpense ", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> wxBudgetedExpense(@RequestParam("areaId") Long areaId,
        @RequestParam(required = true, value = "startLat") Double startLat,
        @RequestParam(required = true, value = "startLng") Double startLng,
        @RequestParam(required = false, value = "endLat") Double endLat,
        @RequestParam(required = false, value = "endLng") Double endLng) {
        Map<String, Object> result = new HashMap<String, Object>();
        BigDecimal money = BigDecimal.ZERO;
        try {
            Double mileage = 0.0;
            Integer time = 0;
            if (startLat != null && startLng != null && endLat != null && endLng != null) {
                Result<Map<String, Long>> tempResult = HttpClientUtil
                    .getDistanceAndTimeValueByTwoPoints(
                        startLng, startLat, endLng, endLat);
                Map<String, Long> result2 = tempResult.getResult();
                Long distance = result2.get("distance");// 米
                Long timemis = result2.get("time");// 秒
                time = (int) (timemis / 60);
                mileage = (double) (distance / 1000);
            }

            Area area = areaService.findOneWithCharge(areaId);
            if (area != null) {

            }

            SelectPrice selectPrice = new SelectPrice();
            selectPrice.setPrice(time, mileage, area, null, 0D);

            money = selectPrice.shouldCash;
            BigDecimal startPrice = selectPrice.qbCost;
            BigDecimal mileagePrice = selectPrice.disCost;
            BigDecimal travelTimePrice = selectPrice.travalTimeCost;
            ChargeStartTime price = selectPrice.getPrice();
            StringBuilder builder = new StringBuilder();
            builder.append("起步价:" + startPrice + "元\n");
            List<ChargeStartDistance> distances = price.getChargeStartDistances();

            if (distances != null && distances.size() != 0) {
                for (ChargeStartDistance d : distances) {
                    builder.append(
                        d.getStartdistance() + "公里到" + d.getDistance() + "公里内,加收" + d.getMoney()
                            + "元");
                    builder.append("\n");
                }
            }

            builder.append("超过" + price.getQblc() + "公里");
            builder.append("以后每" + price.getDjglUnit() + "公里");
            builder.append("加收" + price.getDjglCost() + "元");
            if (price.getDjglThresholdt() != 0) {
                builder.append("(不足" + price.getDjglThresholdt() + "公里不计费)");
            }
            builder.append("\n");
            builder.append("起步后" + price.getQbsj() + "分钟内不收费");
            builder.append("以后每" + price.getDjsjUnit() + "分钟");
            builder.append("加收" + price.getDjsjCost() + "元");
            if (price.getDjsjThresholdt() != 0) {
                builder.append("(不足" + price.getDjsjThresholdt() + "分钟不收费)");
            }
            builder.append("\n");
            builder.append("免费等候" + price.getMfdhsj() + "分钟");
            BigDecimal bigDecimal = price.getDhsjAtonceCost();

            if (bigDecimal.compareTo(BigDecimal.ZERO) == 1) {
                builder.append("到达则立即加收" + price.getDhsjAtonceCost() + "元");
            }
            builder.append("后每" + price.getDhsjUnit() + "分钟");
            builder.append("加收" + price.getDhsjCost() + "元");
            if (price.getDhsjThresholdt() != 0) {
                builder.append("(低于" + price.getDhsjThresholdt() + "分钟不计费)");
            }
            builder.append("\n");
            if (StringUtils.isNotBlank(area.getMemo())) {
                builder.append("备注:" + area.getMemo());
            }
            result.put("pay_detail", builder.toString());
            result.put("money", money != null ? money : 0.0);
            result.put("startPrice", startPrice != null ? startPrice : 0.0); // 起步价
            result.put("mileagePrice", mileagePrice != null ? mileagePrice : 0.0); // 行驶里程费用
            result
                .put("travelTimePrice", travelTimePrice != null ? travelTimePrice : 0.0); // 服务时间费用
            result.put("time", time); // 服务时间
            result.put("mileage", mileage); // 里程
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 0);
            map.put("data", result);
            map.put("message", "预算成功");
            return map;

        } catch (Exception e) {
            e.printStackTrace();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 500);
            map.put("data", null);
            map.put("message", e.getMessage());
            return result;
        }

    }

    /**
     * 获取相向的两条线路
     *
     * @param lineId
     * @param appKey
     * @return
     */
    public String getRelativeLine(Long lineId, String appKey) {
        com.alibaba.fastjson.JSONObject jsonObject = zhuanxianApi.findReturnLine(lineId, appKey);
        com.alibaba.fastjson.JSONObject jj = jsonObject.getJSONObject("data");

        StringBuilder linesBuild = new StringBuilder();
        linesBuild.append(lineId);
        if (null != jj) {
            linesBuild.append(",");
            linesBuild.append(jj.get("id"));
        }
        String result = linesBuild.toString();
        return result;
    }

    /**
     * 查询优惠券
     *
     * @param passengerId
     * @return
     */
    @RequestMapping(value = "queryCoupon", method = RequestMethod.GET)
    @ResponseBody
    public ResultTransport queryCoupon(
        @RequestParam(required = false, value = "passengerId") Long passengerId,
        @RequestParam(required = false, value = "lineId") Long lineId,
        @RequestParam("appKey") String appKey) {
        if (null == passengerId || null == lineId || StringUtils.isBlank(appKey)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }
        String linesId = getRelativeLine(lineId, appKey);
        try {
            List<Coupon> coupons = couponService
                .listByPassenger(passengerId, CouponType.zhuanxian, null, linesId);
            List<Map<String, Object>> couponMapList = new ArrayList<Map<String, Object>>();
            if (!CollectionUtils.isEmpty(coupons)) {
                for (Coupon coupon : coupons) {
                    CouponRule rule = coupon.getCouponRule();
                    Map<String, Object> couponMap = new HashMap<String, Object>();
                    couponMap.put("couponId", coupon.getId());
                    couponMap.put("couponType", rule.getType());
                    couponMap.put("couponMoney", rule.getMoney());
                    couponMap.put("couponDiscount", rule.getDiscount());
                    couponMap.put("couponCode", coupon.getCode());
                    couponMap.put("couponTitle", rule.getTitle());
                    couponMap.put("startTime", rule.getStart().getTime());
                    if (null != rule.getEnd()) {
                        couponMap.put("endTime", rule.getEnd().getTime());
                    } else {
                        couponMap.put("endTime", null);
                    }
                    couponMapList.add(couponMap);
                }
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(couponMapList);

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
        }
    }

    @RequestMapping(value = "clientPayData", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport clientPayData(Long orderId) {
        try {
            Map<String, Object> map = new HashMap<String, Object>();

            Setting setting = settingUtils.get();

            Order order = zhuanxianService.findOne(orderId);
            System.out.println("randomRedPacket:" + order.getRandomRedPacket());
            BigDecimal coupon_hasPayed = new BigDecimal(order.getCouponMoney() == null ? 0.0
                : order.getCouponMoney());

            map.put("couponMoney", coupon_hasPayed);

            map.put("realCash",
                new BigDecimal(order.getRealPay()).subtract(new BigDecimal(order.getGuoluMoney())));
            map.put("guoluMoney", order.getGuoluMoney());
            map.put("yuanchengMoney", order.getYuanchengMoney());
            map.put("otherMoney", null == order.getOtherMoney() ? 0 : order.getOtherMoney());
            map.put("randomRedPacket",
                null == order.getRandomRedPacket() ? 0.0 : order.getRandomRedPacket());

            if (null != order.getPrePayTypeDetail()) {
                if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                    map.put("preyMoney", BigDecimal.ZERO);
                } else {
                    map.put("preyMoney",
                        new BigDecimal(order.getBudgetPay()).subtract(coupon_hasPayed));
                }
            } else {
                map.put("preyMoney", BigDecimal.ZERO);
            }

            if (null != order.getPrePayTypeDetail()) {
                if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                    BigDecimal payMoney = new BigDecimal(order.getRealPay());// 还需支付的钱
                    payMoney = payMoney.subtract(new BigDecimal(order.getGuoluMoney()));
                    payMoney = payMoney.subtract(coupon_hasPayed);
                    if (payMoney.doubleValue() < 0) {
                        payMoney = BigDecimal.ZERO;
                    }
                    payMoney = payMoney.add(new BigDecimal(order.getGuoluMoney()));

                    map.put("payMoney", payMoney);
                } else {
                    map.put("payMoney", order.getRealPay() - order.getBudgetPay());
                }
            } else {
                map.put("payMoney", order.getRealPay());
            }

            Boolean aliPay = true;
            Boolean weixinPay = true;

            if (StringUtils.isBlank(setting.getAlipayPartnerID())
                || StringUtils.isBlank(setting.getAlipaySellerID())
                || StringUtils.isBlank(setting.getAlipayPartnerPrivKey())) {
                aliPay = false;
            }
            if (StringUtils.isBlank(setting.getWxAppID())
                || StringUtils.isBlank(setting.getWxAppSecret())
                || StringUtils.isBlank(setting.getWxPartnerID())
                || StringUtils.isBlank(setting.getWxPartnerKey())) {
                weixinPay = false;
            }

            Boolean unionPay = true;
            if (StringUtils.isBlank(setting.getMerId()) || StringUtils
                .isBlank(setting.getAcpProdEnc())
                || StringUtils.isBlank(setting.getAcpProdMiddle())
                || StringUtils.isBlank(setting.getAcpProdRoot())
                || StringUtils.isBlank(setting.getAcpsdkSignCertPath())
                || StringUtils.isBlank(setting.getAcpsdkSignCertPwd())) {
                unionPay = false;
            }
            map.put("unionPay", unionPay);

            map.put("weixinPay", weixinPay);
            map.put("aliPay", aliPay);
            Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                map.put("overdraw", passenger.isAllowOverdraw());
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                map.put("overdraw", enterprise.isAllowOverdraw());
            }

            map.put("success", true);
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(map);
            return instance;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
        }
    }

    /**
     * 获取支付信息(客户端)
     *
     * @param orderId
     * @return
     */
    @RequestMapping(value = "completeTaskData", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport completeTaskData(Long orderId) {

        log.info("recv orderId:{}", orderId);

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = zhuanxianService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        Driver driver = driverService.findOne(order.getEmployId());
        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_EXISTS);
        }

        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("orderId", order.getId());
            map.put("orderNumber", order.getOrderNo());
            map.put("orderType", "zhuanche");

            map.put("passengerPhone", passenger.getPhone());
            map.put("passengerName", passenger.getName());
            map.put("passengerType", passenger.getTypeStr());

            // 等级
            map.put("passengerGrade", passenger.getGrade_name());

            Company orderCompany = companyService.findOne(order.getCompanyId());
            map.put("orderCompanyName", orderCompany.getAbbreviation());

            Company passengerCompany = companyService.findOne(passenger.getCompanyId());
            map.put("passengerCompanyName", passengerCompany.getAbbreviation());

            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                map.put("overdraw", passenger.isAllowOverdraw());
                map.put("virtual", passenger.getDrawMoney().add(passenger.getNodrawMoney())
                    .setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                map.put("overdraw", enterprise.isAllowOverdraw());
                map.put("virtual", enterprise.getDrawMoney().add(enterprise.getNodrawMoney())
                    .setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            // 优惠券
            if (null != order.getCouponId()) {
                Coupon coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    CouponRule couponRule = coupon.getCouponRule();
                    if (couponRule.getType().equals(CouponRule.TYPE_DEDUCTION)) {
//                        map.put("couponMoney", couponRule.getMoney());
                        map.put("couponMoney", coupon.getCouponPrice());
                    } else if (couponRule.getType().equals(CouponRule.TYPE_DISCOUNT)) {
//                        map.put("discount", couponRule.getDiscount());
                        map.put("discount", coupon.getCouponDiscount());
                    }
                }
            }

            /*
             * //预先支付 BigDecimal preyMoney=BigDecimal.ZERO;
             * if(null!=order.getAlipayMoney() &&
             * order.getAlipayMoney().doubleValue()>0){
             * preyMoney=order.getAlipayMoney(); } else
             * if(null!=order.getWeixinMoney() &&
             * order.getWeixinMoney().doubleValue()>0){
             * preyMoney=order.getWeixinMoney(); } else if(null!=order.getSignMoney()
             * && order.getSignMoney().doubleValue()>0){
             * preyMoney=order.getSignMoney(); } else if(null!=order.getBalanceMoney()
             * && order.getBalanceMoney().doubleValue()>0){
             * preyMoney=order.getBalanceMoney(); } map.put("preyMoney",
             * preyMoney.setScale(2, BigDecimal.ROUND_HALF_UP));
             */
            // 首单免费
            Long completeTimes = firstOrderPassengerService
                .selectAll(passenger.getId(), FirstOrderPassenger.FREE_ORDERTYPE_ZHUANXIAN);
            if (completeTimes > 0) {
                map.put("firstFree", false);
            } else {
                map.put("firstFree", true);
            }

            map.put("employId", driver.getId());
            map.put("employName", driver.getName());
            map.put("employPhone", driver.getPhone());

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(map);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }

    }

    /**
     * 是否支付
     *
     * @param orderId
     * @return
     */
    @RequestMapping(value = "checkTask", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport checkTask(Long orderId) {

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = zhuanxianService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {

            boolean finished = false;
            if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                finished = true;
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(finished);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }

    }

    /**
     * 确认费用接口
     *
     * @param orderId        订单ID
     * @param realCash       订单实际金额
     * @param guoluMoney     过路费
     * @param yuanchengMoney 远程费
     * @param otherMoney     其他费用
     * @param mileage        里程费
     * @param waitedTime     等待时间
     * @param travelTime     执行时间
     * @param toPlace        目的地
     * @param toPlaceLng     目的地经度
     * @param toPlaceLat     目的地纬度
     * @param startPrice     起步费
     * @param mileagePrice   里程费
     * @param runTimePrice   时间费
     * @param waitPrice      等待费用
     * @param memo           备注
     * @param jsonLocs       订单轨迹点
     * @return
     */
    @RequestMapping(value = "confirmTask", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport confirmTask(Long orderId, BigDecimal realCash,
        BigDecimal guoluMoney, BigDecimal yuanchengMoney, BigDecimal otherMoney, Double mileage,
        Integer waitedTime, Integer travelTime,
        @RequestParam(required = false, value = "toPlace") String toPlace,
        @RequestParam(required = false, value = "toPlaceLng") Double toPlaceLng,
        @RequestParam(required = false, value = "toPlaceLat") Double toPlaceLat,
        @RequestParam(required = false, value = "startPrice") BigDecimal startPrice,
        @RequestParam(required = false, value = "mileagePrice") BigDecimal mileagePrice,
        @RequestParam(required = false, value = "runTimePrice") BigDecimal runTimePrice,
        @RequestParam(required = false, value = "waitPrice") BigDecimal waitPrice,
        @RequestParam(required = false, value = "memo") String memo,
        @RequestParam(required = false, value = "jsonLocs") String jsonLocs) {

        return confirmTaskFunction(orderId, realCash, guoluMoney, yuanchengMoney, otherMoney, mileage,
                waitedTime, travelTime, toPlace, toPlaceLng, toPlaceLat, startPrice, mileagePrice,
                runTimePrice, waitPrice, memo, null, null, jsonLocs, null);

    }
    //确认费用
    @RequestMapping(value = "confirmTaskJsonFile", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport confirmTaskJsonFile(Long orderId, BigDecimal realCash,
        BigDecimal guoluMoney, BigDecimal yuanchengMoney, BigDecimal otherMoney, Double mileage,
        Integer waitedTime, Integer travelTime,
        @RequestParam(required = false, value = "toPlace") String toPlace,
        @RequestParam(required = false, value = "toPlaceLng") Double toPlaceLng,
        @RequestParam(required = false, value = "toPlaceLat") Double toPlaceLat,
        @RequestParam(required = false, value = "startPrice") BigDecimal startPrice,
        @RequestParam(required = false, value = "mileagePrice") BigDecimal mileagePrice,
        @RequestParam(required = false, value = "runTimePrice") BigDecimal runTimePrice,
        @RequestParam(required = false, value = "waitPrice") BigDecimal waitPrice,
        @RequestParam(required = false, value = "memo") String memo,
        @RequestParam(required = false, value = "justKilometres") Double justKilometres,
        @RequestParam(required = false, value = "justMoney") BigDecimal justMoney,
        @RequestParam(required = false, value = "jsonLocs") String jsonLocs,
        @RequestParam(required = false, value = "jsonLocFile") MultipartFile jsonLocFile) {

        return confirmTaskFunction(orderId, realCash, guoluMoney, yuanchengMoney, otherMoney,
            mileage,
            waitedTime, travelTime, toPlace, toPlaceLng, toPlaceLat, startPrice, mileagePrice,
            runTimePrice, waitPrice, memo, justKilometres, justMoney, jsonLocs, jsonLocFile);

    }

    private ResultTransport confirmTaskFunction(Long orderId, BigDecimal realCash,
        BigDecimal guoluMoney, BigDecimal yuanchengMoney, BigDecimal otherMoney, Double mileage,
        Integer waitedTime, Integer travelTime, String toPlace, Double toPlaceLng,
        Double toPlaceLat,
        BigDecimal startPrice, BigDecimal mileagePrice, BigDecimal runTimePrice,
        BigDecimal waitPrice, String memo, Double justKilometres, BigDecimal justMoney,
        String jsonLocs, MultipartFile jsonLocFile) {

        log
            .info("recv orderId:{}," + "realCash:{},guoluMoney:{},yuanchengMoney:{},otherMoney:{},"
                    + "mileage:{},waitedTime:{},travelTime:{},"
                    + "toPlace:{},toPlaceLng:{},toPlaceLat:{},"
                    + "startPrice:{},mileagePrice:{},runTimePrice:{},waitPrice:{},memo:{}", orderId,
                realCash,
                guoluMoney, yuanchengMoney, otherMoney, mileage, waitedTime, travelTime, toPlace,
                toPlaceLng, toPlaceLat, startPrice, mileagePrice, runTimePrice, waitPrice, memo);

        if (null == orderId || null == realCash || null == mileage || null == waitedTime
            || null == travelTime || -1 == realCash.compareTo(BigDecimal.ZERO)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }
        Order order = zhuanxianService.findOne(orderId);
        System.out.println("randomRedPacket:" + order.getRandomRedPacket());

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (order.getTreatment()) {
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData("waitfinish");
            return instance;
        }

        try {

            BigDecimal hasPayed = BigDecimal.ZERO;// 之前已经实际支付的钱

            /*
             * hasPayed=hasPayed.add(order.getSignMoney());
             *
             * hasPayed=hasPayed.add(order.getBalanceMoney());
             *
             * hasPayed=hasPayed.add(order.getAlipayMoney());
             *
             * hasPayed=hasPayed.add(order.getWeixinMoney());
             */
            order.setGuoluMoney(guoluMoney.doubleValue());
            order.setYuanchengMoney(yuanchengMoney.doubleValue());
            order.setOtherMoney(otherMoney.doubleValue());
            //支付费用
            order.setRealPay(realCash.doubleValue());
            //如果有随机红包，应付金额减去红包金额
//            Double randomRedPacket = order.getRandomRedPacket();
//            if(null != randomRedPacket){
//                order.setRealPay(realCash.subtract(new BigDecimal(randomRedPacket)).doubleValue());
//            } else {
//                order.setRealPay(realCash.doubleValue());
//            }

            // 优惠券
            Coupon coupon = null;
            BigDecimal coupon_hasPayed = BigDecimal.ZERO;
            Double discount = null;
            if (null != order.getCouponId()) {
                coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
//                        coupon_hasPayed = coupon.getCouponRule().getMoney();
                        coupon_hasPayed = coupon.getCouponPrice();
                    } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
//                        discount = coupon.getCouponRule().getDiscount();
                        discount = coupon.getCouponDiscount();
                        coupon_hasPayed = realCash
                            .subtract(new BigDecimal(order.getGuoluMoney()))
                            .multiply(new BigDecimal(1)
                                .subtract(new BigDecimal(discount).divide(new BigDecimal(10))))
                            .setScale(0, BigDecimal.ROUND_DOWN);
                    }
                }
            }

            order.setCouponMoney(coupon_hasPayed.doubleValue());
            if (coupon_hasPayed.doubleValue() > 0 && null == order.getPrePayTypeDetail()) {
                order.setPrePayTypeDetail(Order.PayTypeDetails.coupon);
            }
            order.setDiscount(discount);

            BigDecimal m = new BigDecimal(mileage);
            double df = m.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
            order.setMileage(df);
            order.setStartWait(waitedTime);
            order.setRunTime(travelTime);

            if (null != startPrice) {
                order.setStartPrice(startPrice.doubleValue());
            }
            if (null != mileagePrice) {
                order.setMileagePrice(mileagePrice.doubleValue());
            }
            if (null != runTimePrice) {
                order.setRunTimePrice(runTimePrice.doubleValue());
            }
            if (null != waitPrice) {
                order.setWaitPrice(waitPrice.doubleValue());
            }

            if (StringUtils.isNotBlank(toPlace) && null != toPlaceLng && null != toPlaceLat) {
                if (StringUtils.isBlank(order.getEndAddress())) {
                    order.setEndLng(toPlaceLng);
                    order.setEndLat(toPlaceLat);
                    order.setEndAddress(toPlace);
                }
            }

            order.setTreatment(true);
            order.setMemo(memo);
            if (null != justKilometres) {
                order.setJustKilometres(justKilometres);
            }
            if (null != justMoney) {
                order.setJustMoney(justMoney);
            }
            Result<Order> result = zhuanxianService.confirmTask(order, null);

            Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
            if (StringUtils.isNotBlank(memo)) {
                passenger.setPlateNumber(memo);
                memberService.updatePassenger(passenger);
            }

            if (result.isSuccess()) {
                // 保存位置
                if (null != jsonLocFile) {
                    jsonLocs = OrderConfirmLocs.locs(jsonLocFile);
                }

                if (StringUtils.isNotBlank(jsonLocs)) {
                    OrderLocationMany orderLocationMany = new OrderLocationMany();
                    orderLocationMany.setOrderId(orderId);
                    orderLocationMany.setOrderType(OrderLocation.OrderType.zhuanxian);
                    orderLocationMany.setJsonLocs(jsonLocs);
                    orderLocationManyService.save(orderLocationMany);
                }

                BigDecimal money = new BigDecimal(order.getRealPay());// 还需支付的钱
                money = money.subtract(new BigDecimal(order.getGuoluMoney()));
                money = money.subtract(coupon_hasPayed);
                if (money.doubleValue() < 0) {
                    money = BigDecimal.ZERO;
                }
                //如果有随机红包，减去红包金额
//                money = money.subtract(new BigDecimal(null == order.getRandomRedPacket() ? 0 : order.getRandomRedPacket()));
                money = money.subtract(hasPayed);
                money = money.add(new BigDecimal(order.getGuoluMoney()));

                // 进入确认页面

                // 客户端提醒付费推送
                ZhuanxianOrderConfirmEvent zhuanxianOrderConfirmEvent = new ZhuanxianOrderConfirmEvent(
                    order);
                applicationEventMulticaster.multicastEvent(zhuanxianOrderConfirmEvent);

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                instance.setData("waitfinish");
                return instance;
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
                return instance;
            }

        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            return instance;
        }
    }

    // 客户端APP后支付
    @RequestMapping(value = "alipay/afterpay")
    public @ResponseBody
    Map<String, Object> alipayAfterpay(HttpServletResponse response,
        HttpServletRequest request, Long orderId) {
        Map<String, Object> resultmap = new HashMap<String, Object>();
        try {

            Order order = zhuanxianService.findOne(orderId);

            if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                resultmap.put("msg", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
                resultmap
                    .put("code", String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()));
                return resultmap;
            }

            if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
                resultmap.put("msg", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
                resultmap.put("code", String.valueOf(ErrorConstantV4.ORDER_STATUS_ERROR.getCode()));
                return resultmap;
            }

            if (!order.getTreatment()) {
                resultmap.put("msg", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
                resultmap.put("code", String.valueOf(ErrorConstantV4.ORDER_NOT_CONFIRM.getCode()));
                return resultmap;
            }

            BigDecimal money = BigDecimal.ZERO;
            if (null != order.getPrePayTypeDetail()) {
                if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                    money = new BigDecimal(order.getRealPay())
                        .subtract(new BigDecimal(order.getCouponMoney()));
                } else {
                    money = new BigDecimal(order.getRealPay() - order.getBudgetPay());
                }
            } else {
                money = new BigDecimal(order.getRealPay());
            }
            //减去随机红包
            if (null != order.getRandomRedPacket()) {
                money = money.subtract(new BigDecimal(order.getRandomRedPacket()));
            }
            money = money.setScale(2, BigDecimal.ROUND_HALF_UP);

            PayRecordOrder payRecordOrder = new PayRecordOrder();
            payRecordOrder.setMoney(money);
            payRecordOrder.setOrderId(orderId);
            payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.alipay);
            payRecordOrder.setTreatment(false);
            Result<PayRecordOrder> result = zhuanxianService.createPayRecordOrder(payRecordOrder);

            Setting setting = settingUtils.get();

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("PartnerID", setting.getAlipayPartnerID());
            map.put("SellerID", setting.getAlipaySellerID());
            map.put("PartnerPrivKey", setting.getAlipayPartnerPrivKey());
            map.put("PartnerPublicKey", AlipayConfig.ali_public_key);
            map.put("tradeNO", "zx_af_" + result.getResult().getId() + "_" + order.getId());
            map.put("productName", "城际专线结算付费");
            map.put("productDescription", "城际专线结算付费");
            map.put("amount", money);
            map.put("notifyURL", setting.getWebUrl() + "/api/zhuanxian/alipay/afternotify");
            String content = MemberOrderSign.sign(map);
            String sign = RSA.sign(content, setting.getAlipayPartnerPrivKey(), "utf-8");
            sign = URLEncoder.encode(sign, "utf-8");
            String url = content + "&sign=\"" + sign + "\"&sign_type=\"RSA\"";
            Map<String, Object> mapData = new HashMap<String, Object>();
            mapData.put("url", url);

            resultmap.put("data", mapData);
            resultmap.put("code", 0);
        } catch (Exception e) {
            resultmap.put("code", ErrorConstantV4.SERVER_ERROR.getCode());
            resultmap.put("msg", ErrorConstantV4.SERVER_ERROR.getMessage());
        }
        return resultmap;
    }

    // 支付宝支付后的接口
    @RequestMapping(value = "alipay/afternotify")
    public synchronized @ResponseBody
    String alipayAfterNotify(HttpServletResponse response,
        HttpServletRequest request) throws UnsupportedEncodingException {
        Setting setting = settingUtils.get();
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr =
                    (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }

            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        // 商户订单号
        String out_trade_no = new String(
            request.getParameter("out_trade_no").getBytes("ISO-8859-1"),
            "UTF-8");
        // 支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),
            "UTF-8");
        // 交易状态
        String trade_status = new String(
            request.getParameter("trade_status").getBytes("ISO-8859-1"),
            "UTF-8");
        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        log.info("商户订单号：" + out_trade_no);
        log.info("交易号：" + trade_no + "交易状态：" + trade_status);
        if (AlipayNotify.verify(params, setting)) {// 验证成功
            if (trade_status.equals("TRADE_FINISHED")) {
                // 调用专车系统支付成功,把临时表的订单信息新增到真实表中
                log.debug("recv alipay out_trade_no:{}", out_trade_no);
                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                PayRecordOrder payRecordOrder = zhuanxianService.findOnePayRecordOrder(orderId);
                if (payRecordOrder.getTreatment()) {
                    return "success";
                }

                Order order = zhuanxianService.findOne(payRecordOrder.getOrderId());

                if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                    return "success";
                }

                Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
                Driver driver = driverService.findOne(order.getEmployId());

                Result<Order> result = zhuanxianService.completeTaskNewV3(order, passenger, driver,
                    "onlinePay", "alipay", null);

                if (result.isSuccess()) {

                    Result<PayRecordOrder> result2 = zhuanxianService
                        .payRecordOrderTreatment(payRecordOrder);

                    if (result2.isSuccess()) {

                        OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                            driver, order.getId(), "zhuanche");
                        applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                        return "success";
                    } else {
                        return "fail";
                    }

                } else {
                    return "fail";
                }

            } else if (trade_status.equals("TRADE_SUCCESS")) {
                // 调用专车系统支付成功,把临时表的订单信息新增到真实表中
                log.debug("recv alipay out_trade_no:{}", out_trade_no);
                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                PayRecordOrder payRecordOrder = zhuanxianService.findOnePayRecordOrder(orderId);
                if (payRecordOrder.getTreatment()) {
                    return "success";
                }

                Order order = zhuanxianService.findOne(payRecordOrder.getOrderId());

                if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                    return "success";
                }

                Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
                Driver driver = driverService.findOne(order.getEmployId());

                Result<Order> result = zhuanxianService.completeTaskNewV3(order, passenger, driver,
                    "onlinePay", "alipay", null);

                if (result.isSuccess()) {

                    Result<PayRecordOrder> result2 = zhuanxianService
                        .payRecordOrderTreatment(payRecordOrder);

                    if (result2.isSuccess()) {

                        OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                            driver, order.getId(), "zhuanxian");
                        applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                        return "success";
                    } else {
                        return "fail";
                    }

                } else {
                    return "fail";
                }

            }

            return "fail";
        } else {
            return "fail";
        }

    }

    // 客户端APP后支付
    @RequestMapping(value = "unionpay/afterpay")
    public @ResponseBody
    Map<String, Object> unionpayAfterpay(HttpServletResponse response,
        HttpServletRequest request, Long orderId) {
        Map<String, Object> resultmap = new HashMap<String, Object>();
        try {

            Order order = zhuanxianService.findOne(orderId);

            if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                resultmap.put("msg", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
                resultmap
                    .put("code", String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()));
                return resultmap;
            }

            if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
                resultmap.put("msg", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
                resultmap.put("code", String.valueOf(ErrorConstantV4.ORDER_STATUS_ERROR.getCode()));
                return resultmap;
            }

            if (!order.getTreatment()) {
                resultmap.put("msg", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
                resultmap.put("code", String.valueOf(ErrorConstantV4.ORDER_NOT_CONFIRM.getCode()));
                return resultmap;
            }

            BigDecimal money = BigDecimal.ZERO;
            if (null != order.getPrePayTypeDetail()) {
                if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                    money = new BigDecimal(order.getRealPay())
                        .subtract(new BigDecimal(order.getCouponMoney()));
                } else {
                    money = new BigDecimal(order.getRealPay() - order.getBudgetPay());
                }
            } else {
                money = new BigDecimal(order.getRealPay());
            }
            money = money.setScale(2, BigDecimal.ROUND_HALF_UP);

            PayRecordOrder payRecordOrder = new PayRecordOrder();
            payRecordOrder.setMoney(money);
            payRecordOrder.setOrderId(orderId);
            payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.alipay);
            payRecordOrder.setTreatment(false);
            Result<PayRecordOrder> result = zhuanxianService.createPayRecordOrder(payRecordOrder);

            Setting setting = settingUtils.get();
            // 从classpath加载acp_sdk.properties文件
            SDKConfig.getConfig().loadPropertiesFromSrc(setting);

            String payOrderId = DemoBase.getOrderId();
            int paymoney = money.multiply(new BigDecimal(100))
                .intValue(); // txnAmt以'元'为单位,乘以100以'分'为单位传给银联
            String txnTime = DemoBase.getCurrentTime(); // 交易时间
            String merId = setting.getMerId(); // 获取商户号
            Map<String, String> contentData = new HashMap<String, String>();

            /*** 银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改 ***/
            contentData.put("version", "5.1.0"); // 版本号 全渠道默认值
            contentData.put("encoding", "UTF-8"); // 字符集编码 可以使用UTF-8,GBK两种方式
            contentData.put("signMethod", "01"); // 签名方法
            contentData.put("txnType", "01"); // 交易类型 01:消费
            contentData.put("txnSubType", "01"); // 交易子类 01：消费
            contentData.put("bizType", "000201"); // 填写000201
            contentData.put("channelType", "08"); // 渠道类型 08手机

            /*** 商户接入参数 ***/
            contentData.put("merId", merId); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
            contentData.put("accessType", "0"); // 接入类型，商户接入填0 ，不需修改（0：直连商户， 1： 收单机构
            // 2：平台商户）
            contentData.put("orderId", payOrderId); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
            contentData
                .put("txnTime", txnTime); // 订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
            contentData.put("accType", "01"); // 账号类型 01：银行卡02：存折03：IC卡帐号类型(卡介质)
            contentData.put("txnAmt", String.valueOf(paymoney)); // 交易金额 单位为分，不能带小数点
            contentData.put("currencyCode", "156"); // 境内商户固定 156 人民币
            String out_trade_no = "zx_af_" + result.getResult().getId() + "_" + order.getId();
            contentData.put("reqReserved", out_trade_no);
            String backUrl = "";
            if (setting.getWebUrl().endsWith("/")) {
                backUrl = setting.getWebUrl() + "api/zhuanxian/unionpay/afternotify";
            } else {
                backUrl = setting.getWebUrl() + "/" + "api/zhuanxian/unionpay/afternotify";
            }
            contentData.put("backUrl", backUrl);

            Map<String, String> reqData = AcpService.sign(contentData,
                DemoBase.encoding); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
            String requestAppUrl = SDKConfig.getConfig()
                .getAppRequestUrl(); // 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
            // acpsdk.backTransUrl
            Map<String, String> rspData = AcpService.post(reqData, requestAppUrl,
                DemoBase.encoding); // 发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过

            if (!rspData.isEmpty()) {
                if (AcpService.validate(rspData, DemoBase.encoding)) {
                    LogUtil.writeLog("验证签名成功");
                    String respCode = rspData.get("respCode");
                    if (("00").equals(respCode)) {
                        String tn = rspData.get("tn");
                        resultmap.put("message", "成功");
                        resultmap.put("code", 0);
                        resultmap.put("data", tn);
                        return resultmap;
                    } else {
                        resultmap.put("message", "验证签名失败");
                        resultmap.put("code", -1);
                        return resultmap;
                    }
                } else {
                    resultmap.put("message", "验证签名失败");
                    resultmap.put("code", -1);
                    return resultmap;
                }
            } else {
                resultmap.put("message", "验证签名失败");
                resultmap.put("code", -1);
                return resultmap;
            }
        } catch (Exception e) {
            resultmap.put("code", ErrorConstantV4.SERVER_ERROR.getCode());
            resultmap.put("msg", ErrorConstantV4.SERVER_ERROR.getMessage());
        }
        return resultmap;
    }

    // 银联支付后的接口
    @RequestMapping(value = "unionpay/afternotify")
    public synchronized @ResponseBody
    void unionpayAfterNotify(HttpServletResponse resp,
        HttpServletRequest req) throws IOException {

        LogUtil.writeLog("BackRcvResponse接收后台通知开始");

        String encoding = req.getParameter(SDKConstants.param_encoding);
        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> reqParam = getAllRequestParam(req);

        LogUtil.printRequestLog(reqParam);

        Map<String, String> valideData = null;
        if (null != reqParam && !reqParam.isEmpty()) {
            Iterator<Entry<String, String>> it = reqParam.entrySet().iterator();
            valideData = new HashMap<String, String>(reqParam.size());
            while (it.hasNext()) {
                Entry<String, String> e = it.next();
                String key = (String) e.getKey();
                String value = (String) e.getValue();
                valideData.put(key, value);
            }
        }

        // 重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
        if (!AcpService.validate(valideData, encoding)) {
            LogUtil.writeLog("验证签名结果[失败].");
            // 验签失败，需解决验签问题
        } else {
            LogUtil.writeLog("验证签名结果[成功].");
            LogUtil.writeLog("后台通知的数据orderId:" + valideData.get("orderId"));
            String respCode = valideData.get("respCode");
            if ("00".equals(respCode)) {
                String out_trade_no = valideData.get("reqReserved"); // 获取后台通知的数据，其他字段也可用类似方式获取
                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                PayRecordOrder payRecordOrder = zhuanxianService.findOnePayRecordOrder(orderId);
                if (!payRecordOrder.getTreatment()) {

                    Order order = zhuanxianService.findOne(payRecordOrder.getOrderId());

                    if (!order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                        Passenger passenger = memberService
                            .findOnePassenger(order.getPassengerId());
                        Driver driver = driverService.findOne(order.getEmployId());

                        Result<Order> result = zhuanxianService
                            .completeTaskNewV3(order, passenger, driver,
                                "onlinePay", "unionpay", null);

                        if (result.isSuccess()) {

                            Result<PayRecordOrder> result2 = zhuanxianService
                                .payRecordOrderTreatment(payRecordOrder);

                            if (result2.isSuccess()) {
                                OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                                    driver, order.getId(), "zhuanxian");
                                applicationEventMulticaster
                                    .multicastEvent(orderPassengerHasPayEvent);
                                // 返回给银联服务器http 200 状态码
                                resp.getWriter().print("ok");
                            }
                        }
                    }
                }
            }
        }
        LogUtil.writeLog("BackRcvResponse接收后台通知结束");
    }

    // 微信支付前接口
    @RequestMapping(value = "wx/afterpay")
    public synchronized @ResponseBody
    Map<String, Object> wxAfterpay(HttpServletResponse response,
        HttpServletRequest request, Long orderId) {

        Order order = zhuanxianService.findOne(orderId);

        Map<String, Object> map = new HashMap<String, Object>();

        if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
            map.put("msg", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
            map.put("code", String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()));
            return map;
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            map.put("msg", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
            map.put("code", String.valueOf(ErrorConstantV4.ORDER_STATUS_ERROR.getCode()));
            return map;
        }

        if (!order.getTreatment()) {
            map.put("msg", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
            map.put("code", String.valueOf(ErrorConstantV4.ORDER_NOT_CONFIRM.getCode()));
            return map;
        }

        BigDecimal money = BigDecimal.ZERO;
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                money = new BigDecimal(order.getRealPay())
                    .subtract(new BigDecimal(order.getCouponMoney()));
            } else {
                money = new BigDecimal(order.getRealPay() - order.getBudgetPay());
            }
        } else {
            money = new BigDecimal(order.getRealPay());
        }
        //减去随机红包
        if (null != order.getRandomRedPacket()) {
            money = money.subtract(new BigDecimal(order.getRandomRedPacket()));
        }
        money = money.setScale(2, BigDecimal.ROUND_HALF_UP);

        PayRecordOrder payRecordOrder = new PayRecordOrder();
        payRecordOrder.setMoney(money);
        payRecordOrder.setOrderId(orderId);
        payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.weixin);
        payRecordOrder.setTreatment(false);
        Result<PayRecordOrder> result = zhuanxianService.createPayRecordOrder(payRecordOrder);

        Setting setting = settingUtils.get();
        String createOrderURL = Configuration.createOrderURL;

        // 商户相关资料
        String appid = setting.getWxAppID();
        String appsecret = setting.getWxAppSecret();
        String partner = setting.getWxPartnerID();
        String partnerkey = setting.getWxPartnerKey();

        // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
        String currTime = TenpayUtil.getCurrTime();
        // 8位日期
        String strTime = currTime.substring(8, currTime.length());
        // 四位随机数
        String strRandom = TenpayUtil.buildRandom(6) + "";
        // 10位序列号,可以自行调整。
        String strReq = strTime + strRandom;
        // 商户号
        String mch_id = partner;
        // 随机数
        String nonce_str = strReq;
        // 商品描述
        String body = "城际专线结算付费-" + order.getOrderNo();
        // 商户订单号
        String out_trade_no = "zx_af_" + result.getResult().getId() + "_" + order.getId();
        // 总金额以分为单位，不带小数点
        String total_fee = String.valueOf(money.multiply(new BigDecimal(100)).intValue());
        // 订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();

        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String notify_url = setting.getWebUrl() + "/api/zhuanxian/wx/afternotify";

        String trade_type = "APP";

        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", out_trade_no);

        // 这里写的金额为1 分到时修改
        // packageParams.put("total_fee", "1");
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);

        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appid, appsecret, partnerkey);

        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
            + "<nonce_str>" + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>"
            + "<body><![CDATA[" + body + "]]></body>" + "<out_trade_no>"
            + out_trade_no
            + "</out_trade_no>"
            +
            // "<total_fee>"+1+"</total_fee>"+
            "<total_fee>" + total_fee + "</total_fee>" + "<spbill_create_ip>" + spbill_create_ip
            + "</spbill_create_ip>" + "<notify_url>" + notify_url + "</notify_url>" + "<trade_type>"
            + trade_type + "</trade_type>" + "</xml>";

        String prepay_id = "";
        try {
            prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
            if (prepay_id.equals("")) {
                log.error("统一支付接口获取预支付订单出错");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        SortedMap<String, String> finalpackage = new TreeMap<String, String>();

        String timestamp = Sha1Util.getTimeStamp();
        finalpackage.put("appid", appid);
        finalpackage.put("partnerid", partner);
        finalpackage.put("prepayid", prepay_id);
        finalpackage.put("package", "Sign=WXPay");
        finalpackage.put("noncestr", nonce_str);
        finalpackage.put("timestamp", timestamp);
        String finalsign = reqHandler.createSign(finalpackage);
        finalpackage.put("sign", finalsign);

        map.put("data", finalpackage);
        map.put("code", 0);

        return map;

    }

    // 微信支付后接口
    @RequestMapping("wx/afternotify")
    public synchronized @ResponseBody
    String wxAfterNotify(HttpServletResponse response,
        HttpServletRequest request) throws Exception {

        String out_trade_no = "";

        try {

            BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            String strxml = sb.toString();

            InputStream in = new ByteArrayInputStream(strxml.getBytes());
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(in);
            Element root = doc.getRootElement();
            List list = root.getChildren();
            Iterator it = list.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String k = e.getName();
                if (k.equals("out_trade_no")) {
                    out_trade_no = e.getText();
                }
            }

            try {
                // 关闭流
                if (null != in) {
                    in.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            log.debug("recv weixin out_trade_no:{}", out_trade_no);

            if (StringUtils.isBlank(out_trade_no)) {
                return "FAIL";
            }

            Long orderId = Long.valueOf(out_trade_no.split("_")[2]);

            PayRecordOrder payRecordOrder = zhuanxianService.findOnePayRecordOrder(orderId);
            if (payRecordOrder.getTreatment()) {
                return "SUCCESS";
            }

            Order order = zhuanxianService.findOne(payRecordOrder.getOrderId());

            if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                return "SUCCESS";
            }

            Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
            Driver driver = driverService.findOne(order.getEmployId());

            Result<Order> result = zhuanxianService.completeTaskNewV3(order, passenger, driver,
                "onlinePay", "weixin", null);

            if (result.isSuccess()) {

                Result<PayRecordOrder> result2 = zhuanxianService
                    .payRecordOrderTreatment(payRecordOrder);

                if (result2.isSuccess()) {

                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver, order.getId(), "zhuanxian");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                    return "SUCCESS";
                } else {
                    return "FAIL";
                }

            } else {
                return "FAIL";
            }

        } catch (Exception e) {
            e.printStackTrace();
            return "FAIL";
        }

    }

    //专线支付费用, 乘客端和司机端都可以调用, 其中司机端的who是null, 乘客端的who是passenger
    @RequestMapping(value = "finishTask", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport finishTask(Long orderId, String payType, String who) {

        log.info("recv orderId:{},payType{}", orderId, payType);

        if (null == orderId || StringUtils.isBlank(payType)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        if (!"helppay".equals(payType) && !"sign".equals(payType) && !"balance".equals(payType)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = zhuanxianService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }
        if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED);
        }
        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (!order.getTreatment()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_CONFIRM);
        }

        Setting setting = settingUtils.get();

        Double afterPayMoney = 0d;//如果有预支付和优惠券,-减掉
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                afterPayMoney = order.getRealPay() - order.getCouponMoney().doubleValue();
            } else {
                afterPayMoney = order.getRealPay() - order.getBudgetPay();
            }
        } else {
            afterPayMoney = order.getRealPay();
        }

        Driver driver = driverService.findOne(order.getEmployId());
        if ("helppay".equals(payType)) {// 如果是代付，服务人员收到现金，余额减钱
            if (afterPayMoney.doubleValue() >= 10000) {
                return ResultTransport.getErrorBy(ErrorConstantV4.HELP_PAY_MONEY_TOOLARGE);
            }
            if (null == driver) {
                return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
            }
//            if (!setting.isAllowHelppayNe()) {
//                if (driver.getVirtual().doubleValue() < (afterPayMoney.doubleValue())) {
//                    return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_MONEY_NOT_ENOUGH);
//                }
//            }
            //$$$ 代付检测
            if (!helppayService
                .checkHelpMoneyEnough(driver.getId(), new BigDecimal(afterPayMoney))) {
                return ResultTransport.getErrorBy(ErrorConstantV4.HELPPAY_MONEY_NOT_ENOUGH);
            }
        }

        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
        if (null != passenger) {
            if ("sign".equals(payType)) {// 签单支付
                if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                    if (!passenger.isAllowOverdraw()) {
                        return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_ALLOW_SIGN);
                    }
                } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    if (!enterprise.isAllowOverdraw()) {
                        return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_ALLOW_SIGN);
                    }
                }
            } else if ("balance".equals(payType)) {// 余额支付
                if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(passenger.getNodrawMoney());
                    if (passenger.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(passenger.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < afterPayMoney) {
                        return ResultTransport
                            .getErrorBy(ErrorConstantV4.PASSENGER_MONEY_NOT_ENOUGH);
                    }
                } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(enterprise.getNodrawMoney());
                    if (enterprise.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(enterprise.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < afterPayMoney) {
                        return ResultTransport
                            .getErrorBy(ErrorConstantV4.PASSENGER_MONEY_NOT_ENOUGH);
                    }
                }

            }
        }

        try {
            Result<Order> result = zhuanxianService
                .completeTaskNewV3(order, passenger, driver, "clickPay", payType, null);

            if (result.isSuccess()) {
                if (StringUtils.isNotBlank(who) && who.equals("passenger")) {
                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver, order.getId(), "zhuanxian");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);
                } else {
                    OrderEmployHasPayEvent orderEmployHasPayEvent = new OrderEmployHasPayEvent(
                        passenger, order.getId(), "zhuanxian");
                    applicationEventMulticaster.multicastEvent(orderEmployHasPayEvent);
                }
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                return instance;
            } else {
                if (result.getErrorcode()
                    .equals(String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()))) {
                    ResultTransport instance = ResultTransport
                        .getErrorBy(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED);
                    return instance;
                } else {
                    ResultTransport instance = ResultTransport
                        .getErrorBy(ErrorConstantV4.SERVER_ERROR);
                    return instance;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            return instance;
        }

    }

    /**
     * 判断司机状态
     *
     * @param employId
     * @return
     */
    @RequestMapping("getBuDanDriverBusy")
    @ResponseBody
    public Map<String, Object> getDriverBusy(Long employId) {
        Map<String, Object> map = new HashMap<String, Object>();
        Boolean kongxian = true;
        String message = "";
        Integer code = 0;

        try {
            Driver driver = driverService.findOne(employId);
            ServiceSetting serviceSetting = ServiceUtil.checkOpen();
            if (serviceSetting.isDaijia()) {
                Long daijiaAmount = orderService.countActivedOrdersByDriver(employId);
                if (daijiaAmount > 0) {
                    System.err.println(driver.getRealname() + "还有未完成的代驾工单,不能补单");
                    kongxian = false;
                    message = "还有未完成的代驾工单,不能补单";
                    code = -1;
                    map.put("success", kongxian);
                    map.put("message", message);
                    map.put("code", code);
                    return map;
                }
            }

            if (serviceSetting.isZhuanche()) {
                Long zhuancheAmount = zhuancheService.countActivedOrdersByDriver(employId);
                if (zhuancheAmount > 0) {
                    System.err.println(driver.getRealname() + "还有未完成的专车工单,不能补单");
                    kongxian = false;
                    message = "还有未完成的专车工单,不能补单";
                    code = -2;
                    map.put("success", kongxian);
                    map.put("message", message);
                    map.put("code", code);
                    return map;
                }
            }

            if (serviceSetting.isPaotui()) {
                Long paotuiAmount = errandService.countBusyAmount(employId);
                if (paotuiAmount > 0) {
                    System.err.println(driver.getRealname() + "还有未完成的跑腿工单,不能补单");
                    kongxian = false;
                    message = "还有未完成的跑腿工单,不能补单";
                    code = -3;
                    map.put("success", kongxian);
                    map.put("message", message);
                    map.put("code", code);
                    return map;
                }
            }

            if (serviceSetting.isFreight()) {
                Long huoyunAmount = freightService.countActivedOrdersByDriver(employId);
                if (huoyunAmount > 0) {
                    System.err.println(driver.getRealname() + "还有未完成的货运工单,不能补单");
                    kongxian = false;
                    message = "还有未完成的货运工单,不能补单";
                    code = -4;
                    map.put("success", kongxian);
                    map.put("message", message);
                    map.put("code", code);
                    return map;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        map.put("success", kongxian);
        map.put("message", message);
        map.put("code", code);
        return map;
    }

    @RequestMapping(value = "getDriverPlace")
    public @ResponseBody
    ResultTransport getDriverPlace(@RequestParam("employId") Long employId) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            if (employId != null) {
                Driver driver = driverService.findOne(employId);
                if (driver != null) {
                    map.put("longitude", driver.getLastLongitude());
                    map.put("latitude", driver.getLastLatitude());
                    map.put("phone", driver.getPhone());
                    try {
                        map.put(
                            "place",
                            HttpClientUtil.getPlaceByLngAndLat(driver.getLastLongitude(),
                                driver.getLastLatitude()));
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                    ResultTransport reponse = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                    reponse.setData(map);
                    return reponse;
                } else {
                    return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
                }

            } else {
                return ResultTransport.getErrorBy(new Error(ErrorConstantV4.PARAM_ERROR.getCode(),
                    "服务人员id不能为空"));
            }
        } catch (Exception e) {
            return ResultTransport.getErrorBy(new Error(ErrorConstantV4.SERVER_ERROR.getCode(),
                "查询服务人员位置错误"));
        }
    }

    @RequestMapping(value = "wx/prepayId_jsapi")
    public synchronized @ResponseBody
    SortedMap<String, String> prepayIdJsapi(
        HttpServletResponse response, HttpServletRequest request, Long orderId, String openid) {

        Order order = zhuanxianService.findOne(orderId);

        SortedMap<String, String> finalpackage = new TreeMap<String, String>();

        if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
            finalpackage
                .put("code", String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()));
            return finalpackage;
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
            finalpackage.put("code", String.valueOf(ErrorConstantV4.ORDER_STATUS_ERROR.getCode()));
            return finalpackage;
        }

        if (!order.getTreatment()) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
            finalpackage.put("code", String.valueOf(ErrorConstantV4.ORDER_NOT_CONFIRM.getCode()));
            return finalpackage;
        }

        BigDecimal money = BigDecimal.ZERO;
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                money = new BigDecimal(order.getRealPay())
                    .subtract(new BigDecimal(order.getCouponMoney()));
            } else {
                money = new BigDecimal(order.getRealPay() - order.getBudgetPay());
            }
        } else {
            money = new BigDecimal(order.getRealPay());
        }
        //减去随机红包
        if (null != order.getRandomRedPacket()) {
            money = money.subtract(new BigDecimal(order.getRandomRedPacket()));
        }
        money = money.setScale(2, BigDecimal.ROUND_HALF_UP);

        PayRecordOrder payRecordOrder = new PayRecordOrder();
        payRecordOrder.setMoney(money);
        payRecordOrder.setOrderId(orderId);
        payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.weixin);
        payRecordOrder.setTreatment(false);
        Result<PayRecordOrder> result = zhuanxianService.createPayRecordOrder(payRecordOrder);

        Setting setting = settingUtils.get();
        WxSetting wxSetting = settingUtils.getWx();

        String createOrderURL = Configuration.createOrderURL;

        // 商户相关资料
        String appid = wxSetting.getWxAppId();
        String appsecret = wxSetting.getWxAppSecret();
        String partner = wxSetting.getWxPartnerId();
        String partnerkey = wxSetting.getWxPartnerKey();

        // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
        String currTime = TenpayUtil.getCurrTime();
        // 8位日期
        String strTime = currTime.substring(8, currTime.length());
        // 四位随机数
        String strRandom = TenpayUtil.buildRandom(6) + "";
        // 10位序列号,可以自行调整。
        String strReq = strTime + strRandom;
        // 商户号
        String mch_id = partner;
        // 随机数
        String nonce_str = strReq;
        // 商品描述
        String body = "城际专线订单结算-" + order.getOrderNo();
        // 商户订单号
        String out_trade_no = "zx_js_" + result.getResult().getId() + "_" + order.getId();
        // 总金额以分为单位，不带小数点
        String total_fee = String.valueOf(money.multiply(new BigDecimal(100)).intValue());
        // 订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();

        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String notify_url = setting.getWebUrl() + "/api/zhuanxian/wx/afternotify";

        String trade_type = "JSAPI";

        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", out_trade_no);

        // 这里写的金额为1 分到时修改
        // packageParams.put("total_fee", "1");
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);
        packageParams.put("openid", openid);

        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appid, appsecret, partnerkey);

        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
            + "<nonce_str>" + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>"
            + "<body><![CDATA[" + body + "]]></body>" + "<out_trade_no>"
            + out_trade_no
            + "</out_trade_no>"
            +
            // "<total_fee>"+1+"</total_fee>"+
            "<total_fee>" + total_fee + "</total_fee>" + "<spbill_create_ip>" + spbill_create_ip
            + "</spbill_create_ip>" + "<notify_url>" + notify_url + "</notify_url>" + "<trade_type>"
            + trade_type + "</trade_type>" + "<openid>" + openid + "</openid>" + "</xml>";

        String prepay_id = "";
        try {
            prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
            if (prepay_id.equals("")) {
                log.error("统一支付接口获取预支付订单出错");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        String timestamp = Sha1Util.getTimeStamp();
        finalpackage.put("appId", appid);
        finalpackage.put("timeStamp", timestamp);
        finalpackage.put("nonceStr", nonce_str);
        finalpackage.put("package", "prepay_id=" + prepay_id + "");
        finalpackage.put("signType", "MD5");
        String finalsign = reqHandler.createSign(finalpackage);
        finalpackage.put("paySign", finalsign);

        return finalpackage;

    }

    // 支付宝支付前接口
    @RequestMapping(value = "bestpay/afterpay")
    public @ResponseBody
    Map<String, Object> bestpayAfterpay(HttpServletResponse response,
        HttpServletRequest request, Long orderId) {
        Map<String, Object> resultmap = new HashMap<String, Object>();
        try {

            Order order = zhuanxianService.findOne(orderId);

            if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                resultmap.put("msg", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
                resultmap
                    .put("code", String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()));
                return resultmap;
            }

            if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
                resultmap.put("msg", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
                resultmap.put("code", String.valueOf(ErrorConstantV4.ORDER_STATUS_ERROR.getCode()));
                return resultmap;
            }

            if (!order.getTreatment()) {
                resultmap.put("msg", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
                resultmap.put("code", String.valueOf(ErrorConstantV4.ORDER_NOT_CONFIRM.getCode()));
                return resultmap;
            }

            BigDecimal money = BigDecimal.ZERO;
            if (null != order.getPrePayTypeDetail()) {
                if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                    money = new BigDecimal(order.getRealPay())
                        .subtract(new BigDecimal(order.getCouponMoney()));
                } else {
                    money = new BigDecimal(order.getRealPay() - order.getBudgetPay());
                }
            } else {
                money = new BigDecimal(order.getRealPay());
            }
            money = money.setScale(2, BigDecimal.ROUND_HALF_UP);

            PayRecordOrder payRecordOrder = new PayRecordOrder();
            payRecordOrder.setMoney(money);
            payRecordOrder.setOrderId(orderId);
            payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.bestpay);
            payRecordOrder.setTreatment(false);
            Result<PayRecordOrder> result = zhuanxianService.createPayRecordOrder(payRecordOrder);

            Setting setting = settingUtils.get();
            Map<String, Object> mapData = new HashMap<String, Object>();
            String callBackUrl = setting.getWebUrl() + "/api/zhuanxian/bestpay/afternotify";
            String createUrl = "https://webpaywg.bestpay.com.cn/order.action";

            // 获取商户信息
            String mch_id = setting.getMerchantId();
            String mch_key = setting.getMerKey();
            String mch_pwd = setting.getMchPwd();
            String riskInfo = setting.getRiskcontrolinfo();
            String attach_order_id = "zx_af_" + result.getResult().getId() + "_" + order
                .getId(); // 商户订单号,这里作为附加信息，因为订单不能个包含特殊字符
            String body = "城际专线结算付费";

            // 使用随机数来作为订单流水号
            String currTime = TenpayUtil.getCurrTime();
            String strTime = currTime.substring(8, currTime.length()); // 8位日期
            String strRandom = TenpayUtil.buildRandom(6) + ""; // 四位随机数
            String strReq = strTime + strRandom; // 10位序列号,可以自行调整

            String phone = order.getPassengerPhone();

            // 格式化金额0.00
            DecimalFormat myformat = new java.text.DecimalFormat("0.00");
            String money_ = myformat.format(money);

            // 订单模型
            String total_fee = String
                .valueOf(money.multiply(new BigDecimal(100)).intValue()); // 元转分
            BestPayOrderModel orderModel = new BestPayOrderModel();
            orderModel.setATTACH(attach_order_id);
            orderModel.setCITYCODE("");
            orderModel.setDIVDETAILS("");
            orderModel.setENCODE("");
            orderModel.setENCODETYPE("1");
            orderModel.setKEY(mch_key);
            orderModel.setLOGINNO("");
            orderModel.setMERCHANTID(mch_id);
            orderModel.setORDERAMT(total_fee); // 分
            orderModel.setORDERCCY("RMB");
            orderModel.setORDERREQTIME(currTime);
            orderModel.setORDERREQTRANSEQ(strReq);
            orderModel.setORDERSEQ(strReq);
            orderModel.setPRODUCTDESC(body);
            orderModel.setPRODUCTID("04");
            orderModel.setPROVINCECODE("");
            orderModel.setRISKCONTROLINFO(riskInfo);
            orderModel.setSERVICECODE("05");
            orderModel.setSESSIONKEY("");
            orderModel.setSUBMERCHANTID("");
            orderModel.setTRANSCODE("01");
            boolean rs = BestPayCreateOrder.createByApp(createUrl, orderModel);

            // 下单失败
            if (!rs) {
                resultmap.put("msg", ErrorConstantV4.BESTPAY_APP_CREATE_ORDER_ERR.getMessage());
                resultmap.put("code",
                    String.valueOf(ErrorConstantV4.BESTPAY_APP_CREATE_ORDER_ERR.getCode()));
                return resultmap;
            }

            // 签名参数
            StringBuffer md5Buffer = new StringBuffer();
            md5Buffer.append("SERVICE=").append("mobile.security.pay").append("&MERCHANTID=")
                .append(mch_id).append("&MERCHANTPWD=").append(mch_pwd).append("&SUBMERCHANTID=")
                .append("").append("&BACKMERCHANTURL=").append(callBackUrl).append("&ORDERSEQ=")
                .append(strReq).append("&ORDERREQTRANSEQ=").append(strReq).append("&ORDERTIME=")
                .append(currTime).append("&ORDERVALIDITYTIME=").append("").append("&CURTYPE=")
                .append("RMB").append("&ORDERAMOUNT=").append(money_).append("&SUBJECT=")
                .append(body)
                .append("&PRODUCTID=").append("04").append("&PRODUCTDESC=").append(body)
                .append("&CUSTOMERID=").append(phone).append("&SWTICHACC=").append("true")
                .append("&KEY=").append(mch_key);

            // 签名
            log.info("MAC(MD5)--before--String：" + md5Buffer.toString());
            String sign = CryptTool.md5Digest(md5Buffer.toString());
            log.info("MAC(MD5)--after--String:" + sign);

            // 拼接返回数据串
            StringBuffer paramsBuffer = new StringBuffer();
            paramsBuffer
                .append("SERVICE=")
                .append("mobile.security.pay")
                .append("&MERCHANTID=")
                .append(mch_id)
                // 签约商户号
                .append("&MERCHANTPWD=").append(mch_pwd).append("&SUBMERCHANTID=").append("")
                .append("&BACKMERCHANTURL=").append(callBackUrl).append("&SIGNTYPE=").append("MD5")
                .append("&SIGN=").append(sign).append("&ORDERSEQ=").append(strReq)
                .append("&ORDERREQTRANSEQ=").append(strReq).append("&ORDERTIME=").append(currTime)
                .append("&ORDERVALIDITYTIME=").append("").append("&ORDERAMOUNT=").append(money_)
                .append("&CURTYPE=").append("RMB").append("&PRODUCTID=").append("04")
                .append("&PRODUCTDESC=").append(body).append("&PRODUCTAMOUNT=").append(money_)
                .append("&ATTACHAMOUNT=").append("0.00").append("&ATTACH=").append(attach_order_id)
                .append("&DIVDETAILS=").append("").append("&ACCOUNTID=").append("")
                .append("&CUSTOMERID=").append(phone).append("&USERIP=").append("")
                .append("&BUSITYPE=")
                .append("04").append("&SWTICHACC=").append("true").append("&SUBJECT=").append(body);

            // 返回数据
            String params = paramsBuffer.toString();
            mapData.put("params", params);
            resultmap.put("data", mapData);
            resultmap.put("code", 0);
        } catch (Exception e) {
            resultmap.put("code", ErrorConstantV4.SERVER_ERROR.getCode());
            resultmap.put("msg", ErrorConstantV4.SERVER_ERROR.getMessage());
        }
        return resultmap;
    }

    // 支付宝支付后的接口
    @RequestMapping(value = "bestpay/afternotify")
    public synchronized @ResponseBody
    String bestpayAfterNotify(HttpServletResponse response,
        HttpServletRequest request) throws UnsupportedEncodingException {

        try {
            // 准备
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();

            // 获取回调数据，注释部分为没有使用的部分数据，其所代表的意义详见翼支付APP文档
            String UPTRANSEQ = request.getParameter("UPTRANSEQ");
            String MERCHANTID = request.getParameter("MERCHANTID");
            String TRANDATE = request.getParameter("TRANDATE");
            String RETNCODE = request.getParameter("RETNCODE");
            String RETNINFO = request.getParameter("RETNINFO");
            // String ORDERREQTRANSEQ = request.getParameter("ORDERREQTRANSEQ");
            String ORDERSEQ = request.getParameter("ORDERSEQ");
            String ORDERAMOUNT = request.getParameter("ORDERAMOUNT");
            // String PRODUCTAMOUNT = request.getParameter("PRODUCTAMOUNT");
            // String ATTACHAMOUNT = request.getParameter("ATTACHAMOUNT");
            // String CURTYPE = request.getParameter("CURTYPE");
            // String ENCODETYPE = request.getParameter("ENCODETYPE");
            // String BANKID = request.getParameter("BANKID");
            String ATTACH = request.getParameter("ATTACH");
            // String UPREQTRANSEQ = request.getParameter("UPREQTRANSEQ");
            // String UPBANKTRANSEQ = request.getParameter("UPBANKTRANSEQ");
            // String PRODUCTNO = request.getParameter("PRODUCTNO");
            String SIGN = request.getParameter("SIGN");

            // 验证签名
            Setting setting = settingUtils.get();
            String key = setting.getMerKey();
            String signStr = "UPTRANSEQ=" + UPTRANSEQ + "&MERCHANTID=" + MERCHANTID + "&ORDERSEQ="
                + ORDERSEQ + "&ORDERAMOUNT=" + ORDERAMOUNT + "&RETNCODE=" + RETNCODE + "&RETNINFO="
                + RETNINFO + "&TRANDATE=" + TRANDATE + "&KEY=" + key;
            String localSign = CryptTool.md5Digest(signStr);

            // 验签失败
            if (!localSign.equals(SIGN)) {
                out.write("UPTRANSEQ_" + UPTRANSEQ);
                log.info("支付回调，验签失败！");
                return "fail";
            }

            // 验签成功，看是否支付成功("0000为成功，其他均为失败")
            if (RETNCODE.equals("0000")) {

                // 调用专车系统支付成功,把临时表的订单信息新增到真实表中
                log.debug("recv bestpay ATTACH:{}", ATTACH);
                Long orderId = Long.valueOf(ATTACH.split("_")[2]);
                PayRecordOrder payRecordOrder = zhuanxianService.findOnePayRecordOrder(orderId);
                if (payRecordOrder.getTreatment()) {
                    return "success";
                }

                Order order = zhuanxianService.findOne(payRecordOrder.getOrderId());

                if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                    return "success";
                }

                Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
                Driver driver = driverService.findOne(order.getEmployId());

                Result<Order> result = zhuanxianService.completeTaskNewV3(order, passenger, driver,
                    "onlinePay", "bestpay", null);

                if (result.isSuccess()) {

                    Result<PayRecordOrder> result2 = zhuanxianService
                        .payRecordOrderTreatment(payRecordOrder);

                    if (result2.isSuccess()) {
                        OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                            driver, order.getId(), "zhuanxian");
                        applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                        return "success";
                    } else {
                        return "fail";
                    }

                } else {
                    return "fail";
                }
            }
            return "fail";
        } catch (Exception e) {
            // 异常不返回，以便不丢失支付数据
            e.printStackTrace();
            return "fail";
        }
    }

}
